package main

var dpin [40]chan pulse        // 数据输入通道数组
var dpout [40][11]chan pulse   // 数据输出通道数组（二维数组）
var shiftin [40]chan pulse     // 移位寄存器输入通道数组
var shiftout [40]chan pulse    // 移位寄存器输出通道数组
var delin [40]chan pulse       // 延迟输入通道数组
var delout [40]chan pulse      // 延迟输出通道数组
var sdin [40]chan pulse        // 特殊数据输入通道数组
var sdout [40]chan pulse       // 特殊数据输出通道数组

func adreset() {
	// 遍历所有索引（0到39）
	for i := 0; i < 40; i++ {
		// 将 dpin 数组中的每个通道设置为 nil
		dpin[i] = nil

		// 将 dpout 数组中的每个子通道设置为 nil
		for j := 0; j < 11; j++ {
			dpout[i][j] = nil
		}

		// 将 shiftin 数组中的每个通道设置为 nil
		shiftin[i] = nil

		// 将 shiftout 数组中的每个通道设置为 nil
		shiftout[i] = nil

		// 将 delin 数组中的每个通道设置为 nil
		delin[i] = nil

		// 将 delout 数组中的每个通道设置为 nil
		delout[i] = nil

		// 将 sdin 数组中的每个通道设置为 nil
		sdin[i] = nil

		// 将 sdout 数组中的每个通道设置为 nil
		sdout[i] = nil
	}
}

func adplug(ilk string, inout, which, param int, ch chan pulse) {
	switch ilk {
	case "dp": // 数据输入输出
		if inout == 0 { // 输入
			dpin[which] = ch
			go digitprog(dpin[which], which) // 启动 digitprog goroutine 处理输入
		} else { // 输出
			dpout[which][param-1] = ch
		}
	case "s": // 移位寄存器输入输出
		if inout == 0 { // 输入
			shiftin[which] = ch
		} else { // 输出
			shiftout[which] = ch
		}
		// 如果输入和输出通道都已设置，则启动 shifter goroutine
		if shiftin[which] != nil && shiftout[which] != nil {
			go shifter(shiftin[which], shiftout[which], param)
		}
	case "d": // 延迟输入输出
		if inout == 0 { // 输入
			delin[which] = ch
		} else { // 输出
			delout[which] = ch
		}
		// 如果输入和输出通道都已设置，则启动 deleter goroutine
		if delin[which] != nil && delout[which] != nil {
			go deleter(delin[which], delout[which], param)
		}
	case "sd": // 特殊数据输入输出
		if inout == 0 { // 输入
			sdin[which] = ch
		} else { // 输出
			sdout[which] = ch
		}
		// 如果输入和输出通道都已设置，则启动 specdig goroutine
		if sdin[which] != nil && sdout[which] != nil {
			go specdig(sdin[which], sdout[which], uint(param))
		}
	}
}

func digitprog(in chan pulse, which int) {
	// 创建响应通道
	resp := make(chan int)

	// 无限循环监听输入通道中的脉冲信号
	for {
		d := <-in // 接收输入通道中的脉冲信号

		// 遍历所有可能的位（0到10）
		for i := uint(0); i < 11; i++ {
			// 检查当前脉冲信号的第 i 位是否为 1
			if d.val&(1<<i) != 0 && dpout[which][i] != nil {
				// 如果第 i 位为 1 并且对应的输出通道不为空，则发送脉冲信号
				dpout[which][i] <- pulse{1, resp}
				<-resp // 等待响应
			}
		}

		// 如果输入脉冲信号包含响应通道，则发送响应
		if d.resp != nil {
			d.resp <- 1
		}
	}
}

func shifter(in, out chan pulse, shift int) {
	for {
		d := <-in // 接收输入通道中的脉冲信号

		if shift >= 0 { // 正向移位
			// 将 d.val 左移 shift 位，并保留最高位（第 10 位）
			d.val = (d.val & (1 << 10)) | ((d.val << uint(shift)) & ((1 << 10) - 1))
		} else { // 负向移位
			// 将 d.val 右移 -shift 位
			x := d.val >> uint(-shift)
			// 如果原始值的第 10 位为 1，则在右移后补上符号扩展
			if d.val&(1<<10) != 0 {
				d.val = x | (((1 << 11) - 1) & ^((1 << uint(11+shift)) - 1))
			} else {
				d.val = x // 否则直接使用右移后的值
			}
		}

		// 如果处理后的脉冲信号值不为 0，则发送到输出通道
		if d.val != 0 {
			out <- d
		} else if d.resp != nil { // 如果脉冲信号包含响应通道且值为 0，则发送响应
			d.resp <- 1
		}
	}
}

func deleter(in, out chan pulse, which int) {
	for {
		d := <-in // 接收输入通道中的脉冲信号

		if which >= 0 { // 删除从最高位开始的低位部分
			// 清除从第 10 位到第 (10 - which) 位的所有位
			d.val &= ^((1 << uint(10-which)) - 1)
		} else { // 删除从最低位开始的高位部分
			// 保留从第 0 位到第 (10 + which) 位的所有位
			d.val &= (1 << uint(10+which)) - 1
		}

		// 如果处理后的脉冲信号值不为 0，则发送到输出通道
		if d.val != 0 {
			out <- d
		} else if d.resp != nil { // 如果脉冲信号包含响应通道且值为 0，则发送响应
			d.resp <- 1
		}
	}
}

func specdig(in, out chan pulse, which uint) {
	for {
		d := <-in // 接收输入通道中的脉冲信号

		// 右移 d.val 的值，移位量为 which
		x := d.val >> which

		// 定义掩码，0x07fc 表示二进制 0000 0111 1111 1100
		mask := 0x07fc

		// 检查 d.val 的第 10 位是否为 1
		if d.val&(1<<10) != 0 {
			// 如果第 10 位为 1，则保留掩码部分
			d.val = x | mask
		} else {
			// 如果第 10 位为 0，则清除掩码部分
			d.val = x & ^mask
		}

		// 如果处理后的脉冲信号值不为 0 并且输出通道不为空，则发送到输出通道
		if d.val != 0 && out != nil {
			out <- d
		} else if d.resp != nil { // 如果脉冲信号包含响应通道且值为 0，则发送响应
			d.resp <- 1
		}
	}
}